package analysis

import (
	"bufio"
	"bytes"
	"encoding/csv"
	"errors"
	"fmt"
	"github.com/cihub/seelog"
	"io"
	"irisysFtp/db"
	"strconv"
	"strings"
	"time"
)

func skyCount(analysis *Analysis) ([]*db.DeviceFlow, error) {
	bo := bufio.NewReader(bytes.NewReader(analysis.Data))
	var allDeviceFlow []*db.DeviceFlow
	for {
		line, _, err := bo.ReadLine()
		if err == io.EOF {
			break
		}
		split := strings.Split(string(line), ";")
		if len(split) != 6 {
			return nil, errors.New("skyCount 格式不对")
		}
		s_5 := strings.Split(split[5], "|")
		if len(s_5) != 8 {
			return nil, errors.New("skyCount 格式不对")
		}
		deviceId := s_5[1]
		dateTime, err := time.ParseInLocation("2006-01-02 15:04:05", s_5[2], time.Local)
		if err != nil {
			return nil, err
		}
		ip := s_5[7]
		for i := 0; i < 4; i++ {
			s_i := split[i]
			s_i_n := strings.Split(s_i, "|")
			for j := 2; j <= 5; j++ {
				j_str := strings.Split(s_i_n[j], ",")
				flow, err := skyCountToDeviceFlow(j_str)
				if err != nil {
					return nil, err
				}
				if flow != nil {
					flow.DeviceId = deviceId
					flow.Time = dateTime
					flow.IpAddress = ip
					allDeviceFlow = append(allDeviceFlow, flow)
				}
			}
		}

	}
	return allDeviceFlow, nil
}

func skyCountToDeviceFlow(arry []string) (*db.DeviceFlow, error) {
	if arry[0] != "0" {
		enter, err := strconv.Atoi(arry[2])
		if err != nil {
			return nil, err
		}
		exit, err := strconv.Atoi(arry[3])
		if err != nil {
			return nil, err
		}
		df := db.DeviceFlow{
			Zone:       arry[0] + arry[1],
			CountEnter: enter,
			CountExit:  exit,
			DeviceType: "skycount",
		}
		return &df, nil
	}
	return nil, nil
}

func irisy(analysis *Analysis) ([]*db.DeviceFlow, error) {
	bo := bufio.NewReader(bytes.NewReader(analysis.Data))
	var allDeviceFlow []*db.DeviceFlow
	for {
		line, _, err := bo.ReadLine()
		if err == io.EOF {
			break
		}
		df, err := irisy2DeviceFlow(string(line))
		if err != nil {
			return nil, err
		}
		allDeviceFlow = append(allDeviceFlow, df)
	}
	return allDeviceFlow, nil
}

/**
日本发送的 irisy 数据解析
*/
func irisy2DeviceFlow(str string) (*db.DeviceFlow, error) {

	arrays := strings.Split(str, "|")
	if len(arrays) == 14 {
		deviceId := fmt.Sprintf("%v-%v-%v", arrays[1], arrays[2], arrays[3])
		dateTime, err := time.ParseInLocation("2006/01/02 15:04:05", arrays[6], time.Local)
		if err != nil {
			return nil, err
		}
		// 减 5min
		m, _ := time.ParseDuration("-5m")
		dateTime = dateTime.Add(m)

		enter, err := strconv.Atoi(arrays[7])
		if err != nil {
			return nil, err
		}
		exit, err := strconv.Atoi(arrays[8])
		if err != nil {
			return nil, err
		}
		ip := arrays[11]

		df := db.DeviceFlow{
			DeviceId:   deviceId,
			Zone:       "0",
			Time:       dateTime,
			CountEnter: enter,
			CountExit:  exit,
			IpAddress:  ip,
			DeviceType: "irisys",
		}
		return &df, nil
	} else {
		return nil, errors.New(fmt.Sprintf("文件内容不匹配：%v", str))
	}
}

func hella(analysis *Analysis) ([]*db.DeviceFlow, error) {
	bo := bufio.NewReader(bytes.NewReader(analysis.Data))
	name := analysis.FileName()
	fileName := name[len(name)-1]
	fileNames := strings.Split(name[len(name)-1], "_")
	if len(fileNames) >= 3 {
		r := csv.NewReader(bo)
		keys, err := r.Read()
		deviceId := fileNames[1]
		var allDeviceFlow []*db.DeviceFlow
		switch fileNames[2] {
		case "data.csv":
			zoneMap := make(map[int]string)
			for index, value := range keys {
				if strings.Contains(value, "_IN") {
					zone := strings.ReplaceAll(value, "_IN", "")
					zoneMap[index] = zone
				}
			}
			if err != nil {
				return nil, err
			}
			for {
				record, err := r.Read()
				if err == io.EOF {
					break
				}
				if len(record) == len(keys) {
					dateTime, err := time.ParseInLocation("2006-01-02 15:04:05", record[1], time.Local)
					if err != nil {
						return nil, err
					}
					m, _ := time.ParseDuration(fmt.Sprintf("-%vs", record[2]))
					dateTime = dateTime.Add(m)
					for k, v := range zoneMap {
						enter, err := strconv.Atoi(record[k])
						if err != nil {
							return nil, err
						}
						exit, err := strconv.Atoi(record[k+1])
						if err != nil {
							return nil, err
						}
						df := db.DeviceFlow{
							DeviceId:   deviceId,
							Zone:       v,
							Time:       dateTime,
							CountEnter: enter,
							CountExit:  exit,
							IpAddress:  "",
							DeviceType: "hella",
						}
						allDeviceFlow = append(allDeviceFlow, &df)
					}
				} else {
					seelog.Errorf("%v data is Incorrect！record:%+v", fileName, record)
				}
			}
			break
		}
		return allDeviceFlow, nil
	} else {
		return nil, errors.New(fmt.Sprintf("this file [%v] is not hella!", fileNames))
	}
}
